#+AUTHOR:Joshua Branson
#+TITLE: C cheatsheat
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}
#+OPTIONS: H:10 toc:nil
* C cheatsheat
** How to say complicated C declarations

http://www.programmerinterview.com/index.php/c-cplusplus/c-declarations/

Begin looking at the variable name.
1) without skipping a right parenthesis, look right and say what you see.  
2) Without skipping a left parenthesis, look left and say what you see.
3) If you are inside a parenthesis, move out of it move to the right to see what you see.
4) Look left and see what you see.  Start again from 1 if need be.


~int (*a)[3];~

Begin by looking at a.
1) Go right and a and hit a right parenthesis.  Do not say anything.
2) Go left of a and say what you see.  Do not pass a left parenthesis.  A pointer.
3) Go outside the parenthesis and see an array of size 3.
4) Go left and see an int.

   SO,  a is a pointer to an array of 3 ints.


~char *i[2][8];~
1) Move right of i and say array of size 2 and an array of size 8.
2) move let of i and say pointer
3) a char

   i is an array composed of 2 arrays of 8 pointers to chars.

~char *(*a[ 3 ])();~

a is an array of size 3 pointers to functions, returning an char pointer


~int (*t[])();~

t

t is an array of points to function returning an int.
** tersely written while loops
#+BEGIN_SRC C
  while (c == getchar())
    putchar (c);
#+END_SRC
** variables and scope
*** automatic variables  aka the default variable scope
Most variables are local to the function that calls them.  That is, any variables declared in a function die when the function exits. For example, the following function =add=, creates the variables a and b in the main function.  BUT they disappear after the function ends.
#+BEGIN_SRC C
  int
  add (int a, int b) {
    return a + b;
  }

  int
  main () {
    printf ("the sum is %s", add (3, 4));
    printf ("a is %s, b is %s", a, b); /* results in error,
                                          because main can't
                                          access a or b. */
    return 0;
  }
#+END_SRC

*** Static varibles
There are also static variables that are static, which keep their values each time they are called.  If you are trying to write functional code, then only use these variables.

#+BEGIN_SRC C :results replace
#include <stdio.h>
  int count () {
    static int b = 0;
    return b++;
  }

  int
  main () {
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    return 0;
  }
#+END_SRC

#+RESULTS:

The output of the above would be

#+BEGIN_SRC C
"b is 1"
"b is 2"
"b is 3"
"b is 4"
#+END_SRC
*** external variables (global)
External variables are variables that are accessible to any function.  They can be thought of as global variables, because any function has access to these global variables.  Never use this functionality.  This is NOT functional programming.  Using global variables usually means that your program will have to run synchrously and not use any threads.  It can also lead to some odd errors.

#+BEGIN_SRC C
#include <stdio.h>

//this is an external variable.  It exists outside all the other functions that call it.
int count = 5;

int add (int a) {
  extern int count;
  return count + a;
}

int
main () {
  extern int count;
  printf ("count == %d\n", count);
  printf ("add (1) == %d \n", add(1));
}
#+END_SRC
** types
*** char
  a singly byte capable of holding 1 character.  A character is any character in ASCII.  It's the english alphabet plus some other characters like "@", "!", "#", "$", "%", etc.

  #+BEGIN_SRC C
  /* Is the ASCII number representing x. */
  char number = 'x';
  /* is the char array "x\0" */
  char x []  = "x";
  #+END_SRC

*** int
  A whole number that can be negative or positive.
  One can also use octal or hexidecimal to define a number
  #+BEGIN_SRC C
    int x = 31;
    /* the same value in octal */
    int x = 037;
    /* int the same value in hexidecimal. */
    int x = 0x1f;
    int x = 0X1F;
  #+END_SRC

  - short int
  - long int
  - unsigned int
    This number is only positive.
  - signed int
    This number is positive and negative.  Dy default "int" is equivalent to "signed int".
*** float
*** double
*** const
  This means that the value will not change.
  #+BEGIN_SRC C
    /* this value cannot be changed. */
    const int x = 6;
  #+END_SRC

I believe that this is a constant too.
#+BEGIN_SRC C
#define NEWLINE '\n'
#+END_SRC
*** enum
The Enumeration constant is a list of constant integer values.  It can often be used for boolean values:

#+BEGIN_SRC C
enum boolean { NO, YES };
#+END_SRC

By default the first element in the list has a value of 0, the next 1, and so on.

You can enumerate the months like so,

#+BEGIN_SRC C
enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
#+END_SRC

** printing arrays
#+BEGIN_SRC C
printf ("%s", "Hello World\n");
#+END_SRC

#+RESULTS:
: Hello World
** Declarations
A variable must be defined, before it can be used.  The following two snippets are identical:

#+BEGIN_SRC C
char my, how, why;
float a, x[1000];
#+END_SRC

#+BEGIN_SRC C
char my;
char how;
char why;
float a;
float x[1000];
#+END_SRC

You can also declare variables with a value:

#+BEGIN_SRC C
char a, b, c = 5;
int o, y, z = 8;
#+END_SRC
** control flow
*** if, else if, else
*** switch

switch (expression) {
   case const-expr: statements
   case const-expr: statements
   default: statements
}


The switch statement is a cool way have multiple if else statements in a better fashion.

I normally use it like so:

#+BEGIN_SRC C :tangle no
  switch (opt)
    {
      // if this parser function is called on an option that it doesn't recognize, then don't do anything.
    default:
      return ARGP_ERR_UNKNOWN;
    case 'j':
      {
        printf ("What do you call a box full of ducks?\n");
        printf ("A bunch of quackers.\n");
        break;
      }

    case 'm':
      {
        //some code
        break;
      }
    }
#+END_SRC

BUT there are cooler ways to use the switch statement!

#+BEGIN_SRC C
  switch (digit) {
   case: 'A' case: 'B' case 'C':
     {
       //some code
     }

   case: 5 case: 7 case: 9
       {
         //some code
         break;
       }
   default:
     //some code
     break;
   }
#+END_SRC
*** for loops

initialize i to be equal to 0, while i is less than 5, do some code.
#+BEGIN_SRC C
for (int i = 0; i < 5; i++) {
//code
}
#+END_SRC

** cool libraries
*** ctype

#+BEGIN_SRC C
isdigit ('c'); //returns false aka non-0.
#+END_SRC

#+BEGIN_SRC C
tolower ('Y'); // returns y
#+END_SRC

#+BEGIN_SRC C
toupper ('z');; // returns z
#+END_SRC
** functions
*** functions may be defined within other functions
** macros

#+BEGIN_SRC C
#define max(A,B)  ((A) > (B) ? (A) : (B))
#+END_SRC

You can also undefine macros.  You might do this to make sure that you are using a function and not a macro:

#+BEGIN_SRC C
#undef max

max (a, b);
#+END_SRC

* virtual memory and paging

A common method of managing memory is by using virtual memory.  Virtual memory is memory that is mapped to physical memory, but usually there is more virtual memory than there is physical memory.  A computer may have 5 GB of real memory, but 6 GB of virtual memory.

Virtual memory is split up into pages, which are normally 4KB each.  A virtual memory page references a real memory page, which is called a frame.  So frames are real memory and pages are virtual memory.

It's like a mormon marriage.  You're supposed to have 1 wife, but the husband gets multiple women.

A process has a page associated with it, but sometimes memory is short and the process' page is not connected to a frame.  When the process tries to use the virtual page, and the virtual page tries to access the frame, this is called a page fault.  When this happens the kernel suspends the process and connects the page to a frame.  Then the kernel starts the process again, and the process thinks that the page was connected to a frame.

It's actually possible to lock pages.  Suppose you have a realtime application that cannot accept page faults, then you can lock that page.  You could also do the same for security sensitive information.  If a process has stored your password, you want that memory only in real memory.  You never want it to get sent to swap...  But locking pages can cause a performance penalty.  If all programs lock pages, then no programs can run.
* argp (argument parsing)

Many C command line programs accept arguments.  Just type =git --help= in a command line to see what I mean.  argp is GNU's standard for dealing with arguments passed to C programs.  Most people will probably only need to call argp_parse in the main function to start using it.


It's a good idea to set some default variables:

=const char * argp_program_version = "VERSION_NUMBER";=
=const char * argp_program_bug_address = "EMAIL_ADDRESS";=
** creating argument parsers

An argument parser is a struct. You probably will need to define options, parser, args_doc, and doc.

#+BEGIN_SRC C
struct argp argp;
#+END_SRC

*** options

The options is just a list of options that this program understands.  Options can be -CHAR or -NAME.

-CHAR is of the form "-g" or "-h" or "-i".

-NAME is of the form "--get" or "--help" or "--i"

For example, one can create an arg_options struct like so:

#+BEGIN_SRC C
  struct argp_option argp_options_joke;
#+END_SRC

Let's suppose you want to make an option that prints a silly joke.  To make the long option be "--joke" you need:

#+BEGIN_SRC C
  argp_options_joke.name = "joke";
#+END_SRC

To have the short option be "-j" :
#+BEGIN_SRC C
  argp_options_joke.key  = 'j';
#+END_SRC

This field needs a name so that argp can associate the option with a parser.
#+BEGIN_SRC C
  argp_options_joke.arg  = "joke";
#+END_SRC

And a doc string
#+BEGIN_SRC C
  argp_options_joke.doc  = "Print a funny joke.";
#+END_SRC

You can also make the option NOT need an argument.  For example the "--help" does not have an argument, but the "rm -r" does require an argument.  In this case "rm -r" requires the file/directory to delete.

#+BEGIN_SRC C
  argp_options_joke.flags = OPTION_ARG_OPTIONAL;  // this option does not need an argument.
#+END_SRC

Now you need to turn this option into an array that can be passed to your argp.options variable.

Notice that the "{ 0 }".  struct argp_option options [2] needs to be a list with the last element in the list having 0 in all of its fields.  "{ 0 }" is the C shortcut for that.

#+BEGIN_SRC C
struct argp_option options [2] = { argp_options_joke, { 0 } };
argp.options = options.
#+END_SRC

*** args_doc
This is the usage string that you print when someone calls your program with PROGRAMNAME --help.

#+BEGIN_SRC C
argp.args_doc = "argp [options]";
#+END_SRC
*** doc

This is the documentation paragraph that explains what your program does.

#+BEGIN_SRC C
argp.doc = "Just a simple test argp program!";
#+END_SRC
*** argp parser functions

argp_parse parses the arguments via an argument parser.  The argument parser could be a null pointer.

The easiest way to use argp to parse options is to use one function to parse all options.  This function needs to look like this:

     =error_t PARSER (int KEY, char *ARG, struct argp_state *STATE)=

The options field in a struct argp points to a function.  Every time this parsing function is called, it parses a command line option.  If the user typed in -j, then KEY equals 'j'.  If the user typed in -g, then the key field equals 'k'.  So you could implement a basic parser function to parse each argument based on what KEY equals.  ie:

#+BEGIN_SRC C :tangle no
error_t
     parse_opt (int key, char *arg, struct argp_state *state)
     {
       switch (key)
         {
         case 'j':
           //some ACTION code here
           break;
         case 'g':
           //some different ACTION code here.
Daisy theme documentation: [[gnus:nnimap+imap.fastmail.com:INBOX#CAHD1g8WjE_jHcX211TYbjZvZWoZdcQF_+2u5s6yq+eaKoDE4XQ@mail.gmail.com][Email from Lindsay V.: Re: Doing some updates]]
           break;
         default:
           return ARGP_ERR_UNKNOWN;
         }
       return 0;
     }

#+END_SRC
* writing a test to prove I know C

[2018-10-30 Tue] I took this test and got a 71%

** what is the [[info:libc#Aborting%20a%20Program][abort]] function?

:answer:
It is a way to abnormally terminate a program.

It does not allow cleanup functions registered with atexit or on_exit.

This function actually terminates with the SIGABRT signal.  My program can include a handler to intercept this signal.
:END:

** types
   What's the differance between a double, float, short, int, long, char,
   etc.
   
   Write some examples of floating numbers, etc.
   
   ie:  9f
   
   Write some hex numbers...
*** How do you write a long double constant?  What letter to you put at the end of the number?

    :ANSWER:
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      int a = 500L;

      int b = 500l;
    #+END_SRC
    :END:
*** How do you write a unsigned long constant?  How do you postfix the number?
    :ANSWER:
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      int a = 240UL;
    
      int b = 212ul;
    #+END_SRC
    :END:
*** What is wrong with this statement
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      short int a = 240UL;
    #+END_SRC

    :ANSWER:
    The declaration (aka "short int a"), implies that a is a short
    integer.  But the definition (240UL), implies that A is an
    unsigned long.  The compiler will probably complain that our
    declaration and definition do not match.
    :END:
*** What is wrong with this statement
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      short int a = 240f;
    #+END_SRC
    
    :ANSWER:
    The declaration (aka "short int a"), implies that a is a short
    integer.  But the definition (240f), implies that A is a floating
    integer.  The compiler will probably complain that our declaration
    and definition do not match.
    :END:
*** Why does C include Hex and octal numbers?  Why don't they just use decimal numbers?

    Because computers only understand 1s and 0s.  There is a conversion
    penalty every time the computer has to convert back and forth between
    binary numbers and decimal digits.
    
    Using Hex numbers can be useful when printing pointer addresses.  A
    program pointer points to a region of memory.  Suppose that a pointer
    address is at the 10,995 byte.  One can write this is binary like
    =0b0010101011110011= or in hex =0x2AF3=
    
    every 4 bits (a nibble), can be represented by one digit in Hex.  This
    saves space.
    
    I still don't know why pointer address's aren't just printed in
    decimal form though.

** do some function pointers
** print a string using only character constants
   
   When I read about string literals on page 194 of the C book, it
   implies that the below code should work...
   
   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("%s", 'a''b''c');
   #+END_SRC

   #+RESULTS:

   Perhaps it was talking about this.
   
   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("%s", "abc" "defg" "hijk");
   #+END_SRC

   #+RESULTS:
   : abcdefghijk
   
   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     char * x = "abc";
     char * y = "def";
     char * z = "g";
     printf ("%s", x y z);
   #+END_SRC

   #+RESULTS:

** if I add in "type.h", then it refuses to [[file:~/programming/c/minify/minify-html.c::/*%20#include%20"types.h"%20*/][compile]]
   :PROPERTIES:
   :ID:       9ac4e026-d625-43cc-acec-ba39de698537
   :END:
   
   why don't [[file:~/programming/c/minify/minify-html.c::/*%20#include%20"types.h"%20*/][this compile?]]
** why would you use the '#' in macro definitions? 

   I found these code snippets in the C coding book
   #+BEGIN_SRC C
     #define tempfile(dir)    #dir "/%s"

     #define cat(x,y)    x ## y
   #+END_SRC

** make some new types aka typedefs

   :ANSWER:
   C does not allow one to extend the language by creating unique new
   definitions.  Rather, it allows one to extend existing types: int,
   long, double, etc.
   
   This is useful for aesthetic and portability reasons.  Consider the
   following:
   
   #+BEGIN_SRC C
     typedef struct complicatedStruct {
       char ** bread;
       int toppings [5];
       double *weight;
       float *size;
     } burger;
   
     // now we can create as many burgers as we want
   
     burger quarterPounder, halfPound, heavyBurger;
   
   #+END_SRC
   
   This can be helpful for portability reasons as well.  Consider a machine that does not have the "float" value.  Then to port the program, all we need to change would be the various typedefs.  Typedefs can also be useful with complicated structures and function pointers like my [[file:~/programming/c/function-pointer.c::int%20(*pAdd4)%20(%20int%20(*%20pAdd3)%20(int%20(*%20pAdd)%20(int,%20int),%20int,%20int,%20int),][function pointer.c]] files shows.
   
   :END:
*** create a function pointer tydedef
:ANSWER:
#+BEGIN_SRC C
typedef int (*functionPointer) (int *, int);
#+END_SRC

:END:

*** create a structure typedef

#+BEGIN_SRC C
  typedef struct {
  char *word;
  char **string;
  char array [];
  } tnode;
#+END_SRC
** what is a multibyte character? 

   
   :answer:
   A multibyte character is a character that takes more than 1 byte to
   encode.  Unicode for example, uses numerous bytes to encode '✯' or 'ϖ'
   for example.
   :END:
** what is a multibyte string? 

   
   :answer:
   This is a string that is composed of entirely multibyte strings.
   :END:

** How do you create a string in C that can hold a unicode character?
   
   :answer:
   L"✡" 
   :END:

** What is a wide string? 

   :answer:
   A wide string is a string that is composed of wchar_t objects.  A
   wide string is usually declared like so: wchar_t * Also most
   unicode strings are going to be wide strings.
   :END:

** What is the equivalent of EOF for wide strings? 
   
   :answer:
   'WEOF' 
   :END:

** what is wrong with this program? 
  
   This program should not be executing!  Malloc is not allocating
   enough memory to hold the string...
   #+HEADERS: :includes <stdio.h> <string.h> <stdlib.h>
   #+BEGIN_SRC C :results output 
     const char * create_hello_string (const char * string)
     {
       char * local_string = (char *) malloc (sizeof (char)); 
       strcpy (local_string, string);
       return local_string;
     }

     int main ()
     {
       char * hello_string = create_hello_string ("hello this string is long.");
       printf("%s\n", hello_string);
       return 0;
     }
   #+END_SRC 

   #+RESULTS:
   : hello this string is lon

** what is the value of i here? 
  
   #+HEADERS: :includes <stdio.h> 
   #+BEGIN_SRC C
     if (1)
       {
         int i = 5;
       }

     printf ("i is %d\n", i);
   #+END_SRC

   #+RESULTS:

   
   :answer:
   i is defined in the if statement scope.  It is not defined in the
   print statement.
   :END:

** How about here? 


   #+HEADERS: :includes <stdio.h> 
   #+BEGIN_SRC C
     for (int i = 0; i < 3; i++)
       ;
     printf ("i is %d\n", i);
   #+END_SRC

   #+RESULTS:
   
   
   :answer:
   'i' is not defined.  'i' is defined inside the scope of the for
   block.  Outside of that block, 'i' does not exist.
   :END:

** This should cause errors but it does not!? Why!? 
  
   #+HEADERS: :includes <stdio.h> 
   #+BEGIN_SRC C :results output
     char * copy_string (char * to, char * from)
     {
       while (*to++ = *from++)
         ;
     }

     int main ()
     {
       char hello [1];
       hello [0] = 'h';
       hello [1] = 'e';
       hello [2] = 'l';
       hello [3] = 'l';
       hello [4] = 'o';
       hello [1000] = '8';
       //copy_string (hello, "hello");
       printf ("hello[] is %s\n", hello);
       putchar (hello [1000]);
       putchar (hello [1001]);
       return 0;
     }
   #+END_SRC

   #+RESULTS:
   : hello[] is hello
   : 8 

** what does "const" in this function declaration mean? 
   
   #+BEGIN_SRC C
     int strlen (const char[]);
   #+END_SRC
   
   :answer:
   This means that the function strlen, will not modify the string
   that is passed to it.
   :END:
   
** vocab
*** what's the stack?
**** print the top two elements of the stack

The stack is what you get your automatic variables.  AKA variable that you don't have to allocate space for via malloc.
*** what's the heap?

The heap contains all of the variables you have got via malloc calls.
*** what's the difference between the stack and the heap

The stack is automatic variables, but the heap is global variables...

The heap are variables that you get via calls to malloc.


The stack are variables you don't have have to use malloc, aka normal or automatic variables.
*** difference between a union and a struct

    :ANSWER:
    Both a union and a struct are an easy way of collecting variables
    under one variable name.  The difference is a struct's collection
    can define all values simultaneously.  A union's collection is
    only allowed to define one variable at a time.
    :END:
*** what's a declaration and a definition and an assignment?

   :ANSWER:
   A declaration is a promise to the compiler that a function or variable exists.
   
   A definition is the section of code that allocates a region of memory for the variable or function.
   
   #+BEGIN_SRC C
     #include <stdio.h>
     int a;     // declaration
     int add (int a, int b);

     int main () {
       a = 5; //this is the assignment statement
       int b = 10; //I am also an assignment statement

       int c = add (a, b);
       printf("%d\n", c);
       return 0;
     }

     //definition
     int add (int a, int b) {
       return a + b;
     }
   #+END_SRC
   
   #+RESULTS:
   : 15
   
   :END:
*** what's a segmentation fault
    :ANSWER:
    Your program tried to access memory to which it did /not/ have access.
    :END:

*** what are the 4 common types of segmentation faults otherwise known as segfaults?

    # retrieved from https://www.cprogramming.com/debugging/segfaults.html
    
    :ANSWER:
    There are four common mistakes that lead to segmentation faults:
    - dereferencing NULL
    - dereferencing an uninitialized pointer
    - dereferencing a pointer that has been freed (or deleted, in C++)
      or that has gone out of scope (in the case of arrays declared in
      functions)
    - writing off the end of an array.
    :END:

*** what's a stack overflow?
    :ANSWER:
    Your recursive function used up all of the stack space.  You have
    no more memory to continue recursing.
    :END:

*** parameter
    
    :ANSWER:
    The parameters are the local variables that are shown in the
    function definition.
    :END:

*** argument

    :ANSWER:
    An argument is the value that is passed to the function.
    :END:

*** what is a statement? 
    Functions are made up of statements, which specify computing
    operations to be done.  Statements are usually one line long and
    end in ";".

** demonstrate proficiency in multidemensional arrays
** argp
** what is the /etc/nsswitch.conf file?

   :answer:
   It is a place to store various information about the system so that
   applications work smoothly together.
   
   /etc/hostname stores the computer's hostname.  That's how the C
   library and everything else know the computer's hostname.
   
   /etc/nsswitch.conf configures other things.
   :END:

** what are some things you could put in the /etc/nsswitch.conf file?

   :answer:
   - email aliases
   - passwords
   - public keys
   - groups of users
   - etc.
   :END:

** threading
** what's the differance between malloc and alloc?

   :answer:
   malloc lets you explicitly allocate memory, and you are responsible
   for destroying that memory.
   
   With alloc you can get memory for yourself, and when you leave the
   function that alloc is called from, the memory is freed
   automatically!  So it's really easy to use, and maybe better!
   :END:

** multi-processing
** do some of the coding challenges provides in my C book
** what's the differance between a pipe and a FIFO?

A pipe has no name.  Only the parent and it's children can communicate with the pipe.

A FIFO is a communication that names a name.  Anyone can open it and communicate to it.
** learn valgrind
http://valgrind.org/docs/manual/quick-start.html#quick-start.mcrun

If run your program with arguments like:  main arg1 arg2,

Then you can run valgrind to test for memory errors like this:

  valgrind --leak-check=yes myprog arg1 arg2

memcheck is the default tool.  --leak-check=yes turns on the detailed memory checker.
** learn complicated declarations

They are read right to left.

** learn programs that tell you how fast your C code is.
** what are signals?
:answer:
Signals are ways for your programs to declare certain events to have happened.
:END:
** What does it mean when a program is given an error signal from the OS?
:answer:
This generally means that the program must stop executing.  Some massive problem has broken significant program logic, exposed a security vulnerability, etc.  Programs can at this time write a core dump file and then return control to the OS to end the program.  This dump file is useful for investigating what caused the crash.
:END:

** how does a C compiler work? initialization
** recursion
** type conversion

Suppose you wish to add an int and a float.  C does a conversion for you.  Generally, the automatic conversions convert a small type to a larger type, so you won't lose information.  IE: C will convert an int into a float to add an int and a float.

#+BEGIN_SRC C :includes <stdio.h>
    int i = 2;
    float f = 3.0;

    printf("%f\n", i + f);
#+END_SRC

#+RESULTS:
: 5.0

** how to code functionally in C?
** #include <filename> vs. #include "filename"?

:ANSWER:
=#include <filename>= is for standard libraries.

=#include "filename"= is for libraries that I write.
:END:

** make a multi-filed C program
** make a portable C program
** learn autotools
** learn macros
*** learn glibc macros
** conditional inclusion:
   #+BEGIN_SRC C
   #if !defined (HDR)
     #if SYSTEM == BSD
      #define HDR "bsd.h"
     #elif SYSTEM == LINUX
      #define HDR == "linux.h"
     #else
      #define HDR "msdos.h"
     #endif
   
     #include HDR
   #+END_SRC
** learn printf

   #+HEADERS: :includes <stdio.h> 
   #+BEGIN_SRC C
     float f = 39403.29304;
     printf ("%%f %f\n", f);
     printf ("%%2f %2f\n", f);
     printf ("%%2.0f %2.0f\n", f);
     printf ("%%100.100f %100.100f\n", f);
   #+END_SRC
   
   #+RESULTS:
   | %f        |   39403.292969 |
   | %2f       |   39403.292969 |
   | %2.0f     |          39403 |
   | %100.100f | 39403.29296875 |


   :ANSWER:
   %d is for decimal
   %6d  is a decimal integer at least 6 characters wide
   %f floating point
   %6f is a floating point at least 6 characters wide
   %.2f  print as a floating point and add two characters after the decimal point
   %6.2f  print as a floating point.  Print 6 characters before the decimal and 2 after
   %o is for octal
   %x for hexadecimal
   %c for character
   %% is for the "%" character.
   :END:

** file descriptors
** Convert these mathematical statements to C statements 

   - (3 / (2 * 4 ^ 9)) - 23 * (4 - 3)
   - π / 23 * (4 / 23)
   - ℇ * 33 (that is Euler's constant)
** specific questions
*** How many bytes does the following string array need?

"Hello\n"

:ANSWER:

7 bytes
|---+---+---+---+---+----+----|
| H | e | l | l | o | \n | \0 |
|---+---+---+---+---+----+----|
:END:
*** What is a global variable in C called? And how would you declare "int n;" to be global?

:ANSWER:
external

#+BEGIN_SRC C
extern int n;
#+END_SRC

:END:
*** How would you define an extern variable inside the function main?

:ANSWER:
You can't.

External variables must be declared outside any function, and they must be declared inside any function that wants to use them.

You can do this though:

#+BEGIN_SRC C
  #include <stdio.h>
  int n;

  int main () {
    extern int n;
    n = 10;

    return n;
  }

#+END_SRC

:END:
*** what's the difference between these definitions/definitions 'char string [] = "hello";' 'char * string = "hello";'

:ANSWER:
This is a string array.
#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C
char string [] = "hello";
printf("%s\n", string);
#+END_SRC

#+RESULTS:
: hello

It is stored in continuous, read/write region of memory like this:

|---+---+---+---+---+----|
| h | e | l | l | o | \0 |
|---+---+---+---+---+----|

I am allowed to alter any character in the string. So
#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C
char string[] = "hello";
string[2] = 'w';
printf ("%s\n", string);
#+END_SRC

#+RESULTS:
: hewlo


This is a string literal
#+BEGIN_SRC C
char * string = "hello";
#+END_SRC

It is stored in a continuous, readonly section of memory like this:

|---------|
| hello\0 |
|---------|

So trying to modify the string results in an error
#+HEADERS: :includes <stdio.h> :var string="hello"
#+BEGIN_SRC C
//char * string = "hello";
string[2] = 'w';
printf ("%s\n", string);
#+END_SRC

#+RESULTS:

:END:
*** What is the function to break a string into tokens?

:answer:
strtok
:END:

*** Describe C's presidence rules...

:ANSWER:
Highest presidence to lowest.   The arithmatic rules are PEMDAS.  So C does not need parenthesis when evaluating
basic arithmetic.

,* /
+ -
> >= < <=
,==   !=
&&  ||
:END:
*** what's the difference between a void function and a static void function?

A void function, can be called by any bit of code in your project.  A static void function, can only be used in the source code file it is in.  This is useful for large projects.  Many drivers in the linux kernel are named static void, so that they do not conflict with any other functions in the linux kernel.
*** what's MT-safe, AS-safe, and AC-safe mean?

:answer:
In POSIX safety terms these refer to if it is safe to call various functions.

MT-safe means that it is safe to call this function inside a thread.  This does not mean that the function is atomic.
:END:
*** What is the difference between 'a' and "a"? 
    
    :answer:
    'a' is a character.  "a" is a string.  "a" is internally
    represented as {'a','\0'}.  
    :END:

** which hurd library is great to develop virtual directory structures like /proc?

:answer:
libnetfs

This is the library that NFS is built on.
:END:
** what is the following output of this C program

#+BEGIN_SRC C
#include <stdio.h>

int main () {
   int *p = 15;
   printf("%d",*p);
   return 0;
}
#+END_SRC

#+RESULTS:

:answer:
A runtime error.  The pointer is not pointing to a proper location in memory.
Trying to read from an undefined point in memory, will cause a segmentation fault.
:END:
** What is the output of these lines of code? 

   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("%d\n", 5/9);
     printf ("%d\n", 5.0/9.0);
     printf ("%f\n", 5.0/9.0);
   #+END_SRC
   
   :answer:
   #+RESULTS:
   |        0 |
   |  4202507 |
   | 0.555556 |
   :END:
   
   Why do they have different output?

   
   :answer:
   The integers 5 and 9 are integers.  However 5.0 and 9.0 are
   considered floating point numbers.  Floating point numbers may have
   information after the decimal point.
   :END:

* I/O
  
Input is reading data.  Output is writing data.  Glibc provides several functions for doing both!

I can read/write to a file by using a stream or a file descriptor.  The stream is supposed to be easier to use.  The file descriptor method is very low level, and streams are built a-top it.  Streams allow 3 different types of buffering.

Streams allow for getting in character by character, or by line by line.

Apparently I should focus on formatted input and formatted output programs...

I will also have file positions.  Whenever I am reading a file, some integer keeps track of where I am in the file.  If I read a byte forward, then that integer increases by 1.

Streams use file pointers.  This is stuff in stdio.h.  I can check to see if I have found the end of the file by calling:

int feof (FILE * STREAM)  it returns non-0 if the end of file is found.

When I call my main function, three streams are defined: stdin, stdout, and stderr.  cool eh?

I can even re-direct stderr to a file:

#+BEGIN_SRC C
  fclose (stdout);
  stdout = fopen ("standard-output-file", "w");
#+END_SRC
** streams
*** Open a stream
file * fopen (const char * FILE, const char * OPENTYPE)

Opentype can be: "r", "w", "a", "r+", "w+", "a+", "m".

"r" is just for reading a file.

"w" is just for writing a file and the previous file contents are discarded.

"a" is for appending at the end of the file.

"r+" is for reading and writing to a file.  This is probably the most useful.

"m" is for opening files via mmap.  It is only used for reading.  This is the function that the Hurd [[file:/ssh:joshua@localhost#2222:/home/joshua/programming/hurd/trans/hello.c::*data%20=%20mmap%20(0,%20amount,%20PROT_READ|PROT_WRITE,%20MAP_ANON,%200,%200);][hello]] program uses.
*** fclose closes the file stream.
int fclose (FILE * stream)
*** putc and fputc

These are how to write one character.  Pretty easy.

put c (int C, FILE * STREAM)
*** puts and fputs

This writes a string to a FILE *.

puts (const char *S, FILE * STREAM)
*** fgetc or getc

These functions get one character from a stream.  It's normally best to use getc, because it's faster.
*** moving the position of the file pointer

fseek (FILE * STREAM, long int OFFSET, int WHENCE)

WHENCE can be SEEK_SET, SEEK_CUR, SEEK_END to indicate if the offset is the relative to current file pointer position, the end of the file, or the beginning of the file.
** perror
is a function that lets you write an error message to the stderr stream.
* pattern matching via regexp
[[info:libc#Regular%20Expressions][info:libc#Regular Expressions]]

This is all stored in regex.h

One first needs to compile a regexp via regcomp (), then one needs to search for matches via regexec ().  Regexec will store the matches in an array that you pass into it.

compiled regular expressions are stored in the data structure regex_t.  Every regex_t has one field that I need: a re_nsub, which holds the compiled regular expressions.

The array has elements of type regmatch_t.  It has two fields:

- rm_so the offset from the beginning of the string.  Add the pointer to the string + rm_so to get the match.

- rm_eo the offset from the end of the string.

  After you have found your matches, be sure to free up the space your compiled regex was using via regfree

#+BEGIN_SRC C :tangle no
regfree (regex);
#+END_SRC
** troubleshooting

grep shows the proper matches in the white-space.txt file:

#+BEGIN_SRC sh :results output :exports both :dir ~/programming/c/
grep -E '[^ ] +$' white-space.txt
#+END_SRC

#+RESULTS:
: This line has extra white space
: this one does bro
: This line definitely has some white space.


BUT this regex doesn't match when I use the C version.  But it does match when I remove the "$".
* searching and strings

    #+HEADERS: :includes <stdio.h> <string.h>
    #+BEGIN_SRC C
      char hello [32] = "Hello World!";
      char * string;
      string = memchr (hello, '!', strlen(hello));
      printf ("%s\n", string);
    #+END_SRC

    #+RESULTS:
    : !
** How do you search trees?

:answer:
tsearch
:END:

* watch some C videos
https://www.youtube.com/user/jstrosch/videos?sort=dd&view=0&shelf_id=1
* data types
** char
** int
** float    single precision floating point
** double   double precision floating point
* qualifiers
These data types do have some qualifiers that can be applied to them.

#+BEGIN_SRC C :tangle no
short int n;
long int m;
#+END_SRC

The above is the same as:

#+BEGIN_SRC C
short n;
long m;
#+END_SRC

You can think of this like sql data types.  a short may have a value between -128-127.  "int" is no smaller than a short, and no larger than a long.
The compiler is free to determine these sizes, based on the hardware.

unsigned or signed may be used for chars and any integer. An unsigned variable's value can never be negative. A signed variable's value can be negative or positive.

#+BEGIN_SRC C
signed int n;
unsigned char c;
signed float f;
long unsigned double d;
#+END_SRC

The qualifier long applied to a double means to make the variable extra precise.

I can specify that a value in C will not change.  If this value is changed, the program will probably abort.
#+BEGIN_SRC C
const int n = 5;
#+END_SRC

* Writing in hexadecimal or octal or scientific notation
** Writing a number is scientific notation

#+BEGIN_SRC C
int n = 101e2;
printf ("%d\n", n);
#+END_SRC

#+RESULTS:
: 10100

#+BEGIN_SRC C
float f = 1.01e2;
printf ("%f\n", f);
#+END_SRC

#+RESULTS:
: 101.0
** writing in binary  this is a GNU extension

#+BEGIN_SRC C
int n = 0b11;
printf ("%d\n", n);
#+END_SRC

#+RESULTS:
: 3

* structs

A struct is a collection of data grouped under one variable name.  This is convenient for large programs with lots of data.  Consider a registration program that is responsible for registering many users.  Each user has a name, address, phone number, etc.  A convenient method for handling this kind of problem is to use a struct.

#+BEGIN_SRC C
  struct human {
    char * phone_number;
    char * name;
    char * address;
  };
#+END_SRC

Then to declare variables of this type one would do the following:

#+BEGIN_SRC C
struct human phil, john, james;
#+END_SRC

Now we have three variables "phil", "john", and "james".  We could now start filling in their information:

#+BEGIN_SRC C
phil.name = "Phil";
john.name = "John";
james.name = "James";
#+END_SRC

We could also do all of the above like this:

#+BEGIN_SRC C
  struct {
    char * name;
    char * phone_number;
    char * address;
  } james, john, phil;

  phil.name = "Phil";
  john.name = "John";
  james.name = "James";
#+END_SRC

But it's more convenient to give the struct a /tag/.  The tag in this case is "human".

Probably the easier way to do all of the above is to do the following:

#+BEGIN_SRC C
  struct human {
    char * name;
    char * phone_number;
    char * address;
  };

  struct human james =  { "James" , "7652834019", "1128 Liby Way New York"   };
  struct human john  =  { "James" , "7642824513", "1128 Liby Way New Jersey" };
  struct human phil  =  { "Phil"  , "7652434074", "1128 Liby Way New York"   };
#+END_SRC

An even easier way would probably be to use a typedef.

#+BEGIN_SRC C
  typedef struct shuman {
    char * name;
    char * phone_number;
    char * address;
  } human_t;  //the "_t" is a hint that this is a typedef

  human james =  { "James" , "7652834019", "1128 Liby Way New York"   };
  human john  =  { "James" , "7642824513", "1128 Liby Way New Jersey" };
  human phil  =  { "Phil"  , "7652434074", "1128 Liby Way New York"   };
#+END_SRC

Here's we've created a structure, and we have given it the typedef "human".  Now we can use this as a way to create new struct "shuman".

** nested structures

We can also nest structures.  Suppose we wanted to create a structure that is a family!  We can do that pretty easily too!
* C coding projects
** writing a basic html parser with the goal of minimizing html files

   The way I had thought about doing it at first was to use the libc
   function strtok, which takes a string, and returns many substrings
   based on a set of string of characters.

   In other words, strtok removes special characters and only returns
   the strings between those special characters.

   So if the string is "<Hello> and </Hello>", and the delimiters are
   "<" and ">", then multiple calls to strtok returns

   strtok () -->  Hello
   strtok () -->   and
   strtok () -->  Hello

   This method worked when I was testing my logic.  Instead of
   specifying an html file, I hardcoded an html string in the file:

   #+BEGIN_SRC C
   const char * string = "<html>real simple</html>";
   #+END_SRC

   BUT now that I want to parse an html file, I may have found a
   better function: getdelim.  getdelim let you read a token from a
   file.  So I probably won't have to use strtok anymore!  I can just
   read the file via getdelim and specify that "<>" are my delimiters.
   The only problem is the getdelim is get delimiter not get
   "delimeters".  So getdelimiter only supports setting a char
   delimeter.  Not a string of delimeters.
   
   I have three possible solutions:
   
   I could ask online...
   - I could write a getdelimeters function...
      - search based   (lots of back and forth of the file)...
      - two different streams for the same file  ()
      - pass over the file with getdelim once with "<", then pass over the file with ">"
      - I could use two loops.  The first loop, uses getdelim "<" and the inner loop uses getdelim ">".
      - parse the whole file into a string, and then use
        strtok. https://stackoverflow.com/questions/174531/easiest-way-to-get-files-contents-in-c
      - memory map the file into memory via mmap

   The main problem with this technique is that the function has a
   hard time processing elements with contents.

   ie:  <p>Hello World</p>

   In the nested while loop, getdelim("<") will return the opening p
   element, but may forget about the p's content.  I could use static
   variables to get around this.


    #+HEADERS: :includes <stdio.h>
    #+BEGIN_SRC C :dir ~/programming/c/
      FILE * file = fopen ("simple.html", "r");
      char ** token;

      const char * getdelimeters (FILE * file, char ** token)
      {
        while ((token = getdelim (token, 128, "<", file)) != NULL)
          {
            //if token does not contain ">"
            return token;
            while ((token = getdelim (token, 128, ">", file)) != NULL)
              {
                //I'll use a static variable here to store the content...
                return token;
              }
          }
        return NULL;
      }

      while ((token = getdelimeters (file, token)) != NULL)
        {
          printf ("Hello%s\n", token);
        }

      fclose (file);
      //getdelim (char ** lineptr, size_t *n, int delimiter, FILE * stream);


    #+END_SRC

    #+RESULTS:

- I could use a combo of strtok and getline
  - copy each line into a const char * and pass it to strtok
** write dummy C compiler that looks for simple problems in C files. :ATTACH:
   :PROPERTIES:
   :ID:       0c70de7f-6ab0-45d2-8353-1366680f4cf3
   :END:
   
   The reference in the back of the C book has some tips about how I
   can compile C.

*** needed datastructes:
**** groups of code
***** expression
      An expression is what is contained inside of parenthesis (also
      can be found inside a printf statement). Can be of a few types
****** comparison
       #+BEGIN_SRC C
         if (1 < 5)
           ;
          else if (3 == 3)
            ;
          else if (2 != 6 )
            ;
       #+END_SRC

       #+RESULTS:

****** assignment 
       
       #+BEGIN_SRC C
         if (x = 1)
           ;
          else if (z = 3 != EOF)
            ;
          else if (2 + 6 == 8)
            ;
       #+END_SRC
****** arithmetic 

       #+BEGIN_SRC C
         if (x + 1)
           ;
          else if (z += 1)
            ;
          else if (y++)
            ;
       #+END_SRC
****** function call 
       
       #+BEGIN_SRC C
         if (isdigit (1))
           ;
          else if (isupper('a'))
            ;
          else if (islower ('b'))
            ;
       #+END_SRC
***** statement
      A statement is any bit of code that ends in a semicolon.  These
      are all statements.
      #+BEGIN_SRC C
        int x = 5;
        x++;
        int b = x - 2;
        int c = x % b;
      #+END_SRC
***** block (aka a compound statement)
      
      Any region of code that is contained between two braces {}, is
      considered a compound statement or a block.  C considers a block
      and a statement as syntactically equivalent. The braces around
      the main function is one block.  An if else statement contains
      two or more blocks.

      #+BEGIN_SRC C
        if (1)
          {
            //first block
          }
         else if (2)
           {
             //second block
           }
         else
           {
             //third block
           }
      #+END_SRC
**** struct function
***** return_type
***** name
***** struct argument
****** type
****** name
**** struct data type
***** char 
***** int
***** float
***** double
**** symbolic constants 
     #+BEGIN_SRC C
     #define name replacement text
     #+END_SRC
**** const bool
**** register bool
**** array escape sequences  
    |----+-----------------+------+--------------------|
    | \a | alert bell      | \\   | backslash          |
    | \b | backspace       | \?   | question mark      |
    | \f | formfeed        | \'   | single quote       |
    | \n | newline         | \"   | double quote       |
    | \r | carriage return | \ooo | octal number       |
    | \v | vertical tab    | \xhh | hexadecimal number |
    |----+-----------------+------+--------------------|
**** array keywords
  |----------+--------+----------+----------|
  | auto     | double | int      | struct   |
  | break    | else   | long     | switch   |
  | case     | enum   | register | typedef  |
  | char     | extern | return   | union    |
  | const    | float  | short    | unsigned |
  | continue | for    | signed   | void     |
  | default  | goto   | sizeof   | volatile |
  | do       | if     | static   | while    |
  |----------+--------+----------+----------|
**** array operators p. 53 
***** should also include order of operations 
**** array types 

     |--------+---------|
     | void   | char    |
     | short  | int     |
     | long   | float   |
     | double | signed  |
     | struct | union   |
     | enum   | typedef |
     |--------+---------|
**** array type qualifiers 
     
     |----------+----------|
     | register | volatile |
     |----------+----------|

**** array storage class specifiers 
     
     | auto    | register |
     | static  | extern   |
     | typedef |          |

**** struct statement
**** struct declaration
**** struct definiton
**** scanf printf, fprintf special  
**** what std libs provide which functions 
***** stdio.h
****** printf
****** fprintf
****** getchar
****** putchar
***** stdlib.h
****** malloc
***** ctype
****** isupper
****** islower
****** isdigit
****** isalpha
***** assert.h 
****** assert
***** errno.h
****** program_name 
****** program_short name
***** argp.h 
**** loops 
***** do while 
***** for 
***** while
**** conditional expressions 
***** if 
***** switch
***** ? : 

*** preprocessing things that I can do before parsing 
**** replace '\''\n' with ''
**** the whole file is split into tokens that are each separated by a white space 
**** comments are replaced by a single space
**** macros are expanded
** copying SIZE bytes from one array to another


   #+HEADERS: :includes <stdio.h> <string.h>
   #+BEGIN_SRC C :dir ~/programming/c/
   
   char string [16] = "hello World\0";
   char other_string [16];
   
   memcpy (other_string, string, 7);
   
   fwrite (other_string, 1, 7, stdout);
   
   #+END_SRC
   
   #+RESULTS:
   : hello W
* more ways to learn C
** The 5 things I could try to learn C faster
https://www.cprogramming.com/how_to_learn_to_program.html
** man pages provide C code examples!  Check out "man getdelim"
** learning how to code https://www.cprogramming.com/how_to_learn_to_program.html
** c reference library http://en.cppreference.com/w/
** c function reference https://www.cprogramming.com/function.html
** c understanding compiler errors https://www.cprogramming.com/tutorial/compiler_linker_errors.html
** learning how to debug C code https://www.cprogramming.com/debugging/segfaults.html
** C programming forum https://cboard.cprogramming.com/cplusplus-programming/69086-parsing-html-files.html
* simple C programs
** creating a simple C program and deleting crucial bits to see what the compiler says 
   
   #+HEADERS  :includes <stdio.h>
   #+BEGIN_SRC C
     int main () 
     {
       printf ("Hello World\n");
       return 0;
     }
   #+END_SRC

   #+RESULTS:
   : Hello World
   
   #+HEADERS  :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("Hello World\n")
   #+END_SRC

   #+RESULTS:
   
   #+BEGIN_SRC C
     #include <stdio.h>

     main ()
     {
       printf ("Hello World\n");
     }
   #+END_SRC

   #+RESULTS:

      #+BEGIN_SRC C
        #include <stdio.h>

        int main ()
        {
          printf ("Hello World\n");
        }
   #+END_SRC

   #+RESULTS:
   : Hello World

   
   #+BEGIN_SRC C
     #include <stdio.h>

     void main ()
     {
       printf ("Hello World\n");
     }
   #+END_SRC

   #+RESULTS:

   #+BEGIN_SRC C
     include <stdio.h>

     int main ()
     {
       printf ("hello World\n");
       return 0;
     }
   #+END_SRC 

   #+RESULTS:

   #+BEGIN_SRC C
     #include <stdio.h

     int main ()
     {
       printf ("hello World\n");
       return 0;
     }
   #+END_SRC 

   #+RESULTS:
   
   #+BEGIN_SRC C
     #include <stdio.h>

     int main ()
     {
       printf ("hello \e \a \f \< \( < \@ \5 World\n");
       return 0;
     }
   #+END_SRC 

   #+RESULTS:
   : hello    < ( < @  World
** a function that reverses a string 
   #+HEADERS: :includes <stdio.h> <stdlib.h> <string.h>
   #+BEGIN_SRC C
     char * reverse (char * to, char * from)
     {
       int i, j;
       for (j = 0, i = strlen (from) - 1; (*(to + j) = *(from + i)) && i > 0; i--, j++)
         ;
     }

     int main ()
     {
       char * str = (char *) malloc (sizeof("hello"));
       reverse (str, "hello");
       printf ("%s\n", str);
       putchar (*(str + 10)); //why does this not cause an error?
       return 0;
     }
   #+END_SRC

   #+RESULTS:
   | olleh |
   |      |
** strlen 
  
   #+HEADERS: :includes <stdio.h> <string.h> 
   #+BEGIN_SRC C
     printf ("strlen is %d\n", strlen("ab"));
   #+END_SRC

   #+RESULTS:
   : strlen is 2
** subtracting 'char's 
   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("'c' - 'a' = %d\n", 'c' - 'a'); 
   #+END_SRC

   #+RESULTS:
   : 'c' - 'a' = 2

** outputting an ASCII chart 
   #+BEGIN_SRC C
     #include <stdio.h>

     int main()
     {
       char a [] = "abcdefghijklmnopqrstuvwxyz";
       char A [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

       for (int i = 0; i < 26; i++)
         {
           printf ("%c %d %c %d %d %d\n", a[i], a[i], A[i], A[i], i < 10 ? i : 0, i < 10 ? (int) (i+48) : ' '); 
         }
       return 0;
     }

   #+END_SRC 

   #+RESULTS:
   |  a |  97 | A | 65 | 0 | 48 |
   | 48 |  49 |   |    |   |    |
   |  b |  98 | B | 66 | 1 | 49 |
   | 48 |  49 |   |    |   |    |
   |  c |  99 | C | 67 | 2 | 50 |
   | 48 |  49 |   |    |   |    |
   |  d | 100 | D | 68 | 3 | 51 |
   | 48 |  49 |   |    |   |    |
   |  e | 101 | E | 69 | 4 | 52 |
   | 48 |  49 |   |    |   |    |
   |  f | 102 | F | 70 | 5 | 53 |
   | 48 |  49 |   |    |   |    |
   |  g | 103 | G | 71 | 6 | 54 |
   | 48 |  49 |   |    |   |    |
   |  h | 104 | H | 72 | 7 | 55 |
   | 48 |  49 |   |    |   |    |
   |  i | 105 | I | 73 | 8 | 56 |
   | 48 |  49 |   |    |   |    |
   |  j | 106 | J | 74 | 9 | 57 |
   | 48 |  49 |   |    |   |    |
   |  k | 107 | K | 75 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  l | 108 | L | 76 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  m | 109 | M | 77 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  n | 110 | N | 78 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  o | 111 | O | 79 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  p | 112 | P | 80 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  q | 113 | Q | 81 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  r | 114 | R | 82 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  s | 115 | S | 83 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  t | 116 | T | 84 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  u | 117 | U | 85 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  v | 118 | V | 86 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  w | 119 | W | 87 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  x | 120 | X | 88 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  y | 121 | Y | 89 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
   |  z | 122 | Z | 90 | 0 | 32 |
   | 48 |  49 |   |    |   |    |
  
   #+HEADERS: :include <stdio.h> 
   #+BEGIN_SRC C
     #include <stdio.h>

     int main ()
     {
       printf ("%d", (26 % 26));
       return 0;
     }
   #+END_SRC

   #+RESULTS:
   : 0
** expand string  

   This simple function will try to expand strings like "a-d" into
   "abcd".  Eventually try to handle "0-9" and even "a-z0-9"
   
   !*p is how you can test if your pointer currently points at the
     '\0' character.
   #+HEADERS: :includes <stdio.h> <stdlib.h>
   #+BEGIN_SRC C
     // sequence_t will store the information from an encoded string the
     // encoded strings looks like "[a-zA-Z0-9]-[a-zA-Z0-9]".  So an
     // encoded string of "a-z", represents the whole alphabet.

     //A struct of
     //sequence_t = {beginning_char = 'a', end_char = 'z', next
     // = sequence_t { beginning_char = '0', end_char = '9', next = 0 }}
     // represents a string that contains the alphabet followed by the
     // numbers 1-9.  The original string would have been "a-z0-9".
     struct sequence_t
     {
       char beginning_char, end_char;
       unsigned int sequence_length;
       struct sequence_t *next;
     };

     struct sequence_t * allocate_sequence ()
     {
       struct sequence_t * sequence = 
         (struct sequence_t *) malloc (sizeof (struct sequence_t));
       return sequence; 
     }

     struct sequence_t * parse_string (char * str)
     {
       struct sequence_t * sequence = allocate_sequence();
       sequence->beginning_char = *str;
       sequence->end_char = *(str + 2);
     }

     char * expand (char * input_string)
     {
       struct sequence_t * sequence = parse_string (input_string);
       char * loop_str;
       char * temp_str;
       char * return_string = 0;
       while (!sequence->next)
         {
           loop_str = (char *) malloc (sizeof (char) * 32);
           int i = 0;
           //
           for (char c = sequence->beginning_char; c <= sequence->end_char; c++, i++) 
             ,*(loop_str + i) = c;
           ,*(loop_str + i) = '\0';
           if (!return_string) 
             return_string = loop_str;
           else
             {
               return_string =
                 (char *) realloc (return_string, (sizeof (char) * strlen (return_string)
                                                   + (sizeof (char) * 32)));
               strcpy ((return_string + strlen (return_string)), loop_str);
             }
         }
       return return_string;
     }

     int main ()
     {
       char * string = expand ("a-z"); 
       printf ("%s\n", string);
       return 0;
     }
   #+END_SRC

   #+RESULTS:

** temperature
  

*** temperature printing and integer truncating
     #+HEADERS: :includes <stdio.h>
     #+BEGIN_SRC C
       int main ()
       {
         int fahr, celsius;
         int lower, upper, step;
     
         lower = 0;                    /* lower limit of temperature table */
         upper = 300;                  /* upper limit */
         step = 20;                    /* step size */
     
         fahr = lower;
         printf ("Fahrenheit Celsius\n");
         while (fahr <= upper)
           {
             celsius = 5 * (fahr - 30) / 9;
             //celsius = (fahr - 30) * (5/9);  //this is wrong
             //in C integer division, truncates any remainder
             // aka  5 / 9 = .55555, but in C  5/9 == 0
             printf ("%d %d\n", fahr, celsius);
             fahr = fahr + step;
           }
         return 0;
       }
     #+END_SRC
     
     #+RESULTS:
     | Fahrenheit | Celsius |
     |          0 |     -16 |
     |         20 |      -5 |
     |         40 |       5 |
     |         60 |      16 |
     |         80 |      27 |
     |        100 |      38 |
     |        120 |      50 |
     |        140 |      61 |
     |        160 |      72 |
     |        180 |      83 |
     |        200 |      94 |
     |        220 |     105 |
     |        240 |     116 |
     |        260 |     127 |
     |        280 |     138 |
     |        300 |     150 |
*** temperature conversion more accurate

#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C

  int main ()
  {
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;
    upper = 300;
    step = 10;

    fahr = lower;
    printf ("Fahrenheit Celsius\n");
    while (fahr <= upper)
      {
        /* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
        celsius = (5.0 / 9.0) * (fahr - 32.0);
        /* 3.0, means print at least 3 characters wide with no decimal digit */
        /* 6.1 means print at least 8 characters wide with 3 decimal digits */
        printf ("%3.0f %8.3f\n", fahr, celsius);
        fahr = fahr + step;
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
| Fahrenheit | Celsius |
|          0 | -17.778 |
|         10 | -12.222 |
|         20 |  -6.667 |
|         30 |  -1.111 |
|         40 |   4.444 |
|         50 |    10.0 |
|         60 |  15.556 |
|         70 |  21.111 |
|         80 |  26.667 |
|         90 |  32.222 |
|        100 |  37.778 |
|        110 |  43.333 |
|        120 |  48.889 |
|        130 |  54.444 |
|        140 |    60.0 |
|        150 |  65.556 |
|        160 |  71.111 |
|        170 |  76.667 |
|        180 |  82.222 |
|        190 |  87.778 |
|        200 |  93.333 |
|        210 |  98.889 |
|        220 | 104.444 |
|        230 |   110.0 |
|        240 | 115.556 |
|        250 | 121.111 |
|        260 | 126.667 |
|        270 | 132.222 |
|        280 | 137.778 |
|        290 | 143.333 |
|        300 | 148.889 |
*** temperature conversion more accurate celsius --> fahrenheit

#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C

  int main ()
  {
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;
    upper = 300;
    step = 10;

    celsius = lower;
    printf ("Celsius Fahrenheit\n");
    while (celsius <= upper)
      {
        /* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
        fahr = (5.0 / 9.0) * celsius + 32;
        /* 3.0, means print at least 3 characters wide with no decimal digit */
        /* 6.1 means print at least 8 characters wide with 3 decimal digits */
        printf ("%3.0f %5.1f\n", celsius, fahr);
        celsius = celsius + step;
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
| Celsius | Fahrenheit |
|       0 |       32.0 |
|      10 |       37.6 |
|      20 |       43.1 |
|      30 |       48.7 |
|      40 |       54.2 |
|      50 |       59.8 |
|      60 |       65.3 |
|      70 |       70.9 |
|      80 |       76.4 |
|      90 |       82.0 |
|     100 |       87.6 |
|     110 |       93.1 |
|     120 |       98.7 |
|     130 |      104.2 |
|     140 |      109.8 |
|     150 |      115.3 |
|     160 |      120.9 |
|     170 |      126.4 |
|     180 |      132.0 |
|     190 |      137.6 |
|     200 |      143.1 |
|     210 |      148.7 |
|     220 |      154.2 |
|     230 |      159.8 |
|     240 |      165.3 |
|     250 |      170.9 |
|     260 |      176.4 |
|     270 |      182.0 |
|     280 |      187.6 |
|     290 |      193.1 |
|     300 |      198.7 |
*** temperature via for loop

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    int fahr;

    for (fahr = 0; fahr <= 300; fahr = fahr + 20)
      {
        printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
|   0 | -17.8 |
|  20 |  -6.7 |
|  40 |   4.4 |
|  60 |  15.6 |
|  80 |  26.7 |
| 100 |  37.8 |
| 120 |  48.9 |
| 140 |  60.0 |
| 160 |  71.1 |
| 180 |  82.2 |
| 200 |  93.3 |
| 220 | 104.4 |
| 240 | 115.6 |
| 260 | 126.7 |
| 280 | 137.8 |
| 300 | 148.9 |
*** temperature via for loop with constants

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  #include <stdio.h>

  #define LOWER 0
  #define UPPER 300
  #define STEP 20

  int main ()
  {
    int fahr;

    for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
      {
        printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
|   0 | -17.8 |
|  20 |  -6.7 |
|  40 |   4.4 |
|  60 |  15.6 |
|  80 |  26.7 |
| 100 |  37.8 |
| 120 |  48.9 |
| 140 |  60.0 |
| 160 |  71.1 |
| 180 |  82.2 |
| 200 |  93.3 |
| 220 | 104.4 |
| 240 | 115.6 |
| 260 | 126.7 |
| 280 | 137.8 |
| 300 | 148.9 |
** printing chars
*** what's wrong with this code?

A program that outputs it's input
#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C

  char c;

  c = getchar ();
  while (c != EOF)
    {
      putchar (c);
      c = getchar ();
    }

#+END_SRC

#+RESULTS:

char c;  That's the problem.  char c can only hold 128 characters.  It is not large enough to hold the EOF character.  So c must be declared in int.
*** simpler version

#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    int c;

    while ((c = getchar()) != EOF)
      putchar (c);

    return 0;
  }
#+END_SRC

#+RESULTS:
*** program to print value of EOF

#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    printf("%d\n", EOF);
    return 0;
  }

#+END_SRC

#+RESULTS:
: -1
*** counting lines

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  int main ()
  {

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nl;

    nl = 0;

    while ((c = fgetc(stream)) != EOF)
      if (c == '\n')
        ++nl;

    printf ("number of lines in %s is %d\n", string, nl);

    return 0;
  }
#+END_SRC

#+RESULTS:
: number of lines in silly.txt is 9
*** counting lines, blanks, tabs

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  int main ()
  {

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nl, tabs, blanks = 0;

    while ((c = fgetc(stream)) != EOF)
      switch (c)
        {
        case '\n':
          ++nl;
          break;

        case '\t':
          ++tabs;
          break;

        case ' ':
          ++blanks;
          break;
        }
    printf ("number of lines in %s is %d\n", string, nl);
    printf ("number of blanks in %s is %d\n", string, blanks);
    printf ("number of tabs in %s is %d\n", string, tabs);

    return 0;
  }
#+END_SRC

#+RESULTS:
| number | of | lines  | in | silly.txt | is |  9 |
| number | of | blanks | in | silly.txt | is | 16 |
| number | of | tabs   | in | silly.txt | is |  0 |
*** counting words and characters  there's something wrong here

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
   #include <stdio.h>

   #define IN  1
   #define OUT 0

   int main ()
   {

     char string [16] = "silly.txt";

     FILE * stream = fopen (string, "r");

     int c, nc, nl, nw, state = 0;

     while ((c = fgetc (stream)) != EOF)
       {
         ++nc;
         if (c == '\n')
           ++nl;

         if (c == '\n' || c == ' ' || c == '\t')
           state = OUT;
         else
           {
             if (state == OUT)
               state = IN;
             ++nw;
           }
       }

     printf ("%s has %d lines, %d words, and %d characters\n", string, nl, nw, nc);

     return 0;
   }
#+END_SRC

#+RESULTS:
| silly.txt has 9 lines | 32934 words | and 193 characters |

*** print a file with each word on each line

#+BEGIN_SRC C  :dir ~/manuals/cheatsheets/text-files/  :includes <stdio.h>  :defines OUT 0 IN 1

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nc, nl, nw, state = 0;

    while ((c = fgetc (stream)) != EOF)
      {
        if (c == ' ')
          {
            state = OUT;
            printf("\n");
          }
        else
          {
            if (state == OUT)
              state = IN;
            fputc (c, stdout);
            state = IN;
            ++nw;
          }
      }
#+END_SRC

#+RESULTS:
| #+AUTHOR:Joshua          |
| Branson                  |
| #+TITLE:                 |
| #+LATEX_HEADER:          |
| \usepackage{lmodern}     |
| #+LATEX_HEADER:          |
| \usepackage[QX]{fontenc} |
| #+OPTIONS:               |
| H:10                     |
| toc:nil                  |
|                          |
| *                        |
| This                     |
| is                       |
| a                        |
| silly                    |
| Text                     |
| File                     |
|                          |
| I'm                      |
| using                    |
| it                       |
| to                       |
| count                    |
| lines                    |
|                          |
| to                       |
| to                       |
| to                       |
*** print a histogram of the length of words in a file what's wrong here?

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  #define IN  1
  #define OUT 0
  #define MAX_WORD_LENGTH  32

  int main ()
  {

    char string [16] = "silly.txt";
    /* word_length[5] = 7, means that there were 7 words of length 5; */
    int word_lengths [MAX_WORD_LENGTH];

    /* initialize word_lengths to 0 */
    for (int i = 0; i < MAX_WORD_LENGTH; i++)
      word_lengths[i] = 0;


    FILE * stream = fopen (string, "r");

    /* nw == new word */
    /* wl == word length */
    int c, nw, wl, state = 0;

    while ((c = fgetc (stream)) != EOF)
      {
        /* if this is NOT a word, state is now OUT of word */
        if (c == '\n' || c == ' ' || c == '\t')
          {
            state = OUT;
            if (wl > 0)
              {
                word_lengths[wl] = word_lengths[wl] + 1;
              }
            wl = 0;
          }
        else //state is now IN a word
          {
            if (state == OUT)
              {
                state = IN;
                ++nw;
              }
            ++wl;
          }
      }

    printf ("%s has %d words\n", string, nw);

    //print the histogram of word lengths
    //ie:
    /* word_lengths = {0, 1, 4, 5}
       output is :

       1 -
       2 ----
       3 -----
    ,*/

    for (int i = 1; i < MAX_WORD_LENGTH; i++)
      {
        if (word_lengths[i])
          {
            printf("%d ", i);
            for (int j = 0; j < word_lengths[i]; j++)
              fputc ('-', stdout);
            printf("\n");
          }
      }

    return 0;
  }
#+END_SRC

#+RESULTS:
** write a C program to determine the size of float, double, and long double.

The headers <limits.h> and <float.h> should be helpful to do this.
** Bitwise programs
*** Turning off the lower 7 bits of a number

#+BEGIN_SRC C  :includes <stdio.h>
  int b = 0b111111111111;

  printf("%d %d %d\n", b, 0177, b & 0177);

  int c = 0b111110000000;

  printf("%d %u\n", c, c);
#+END_SRC

#+RESULTS:
| 4095 |  127 | 127 |
| 3968 | 3968 |     |
** write a program to use alloc [[info:libc#Variable%20Size%20Automatic][info:libc#Variable Size Automatic]]
** make a C function to print a decimal number in binary

#+BEGIN_SRC C :includes '("<stdio.h>" "<math.h>") :flags -lm :defines MAX_NUMBER 128
  /* This function takes an int and prints its binary representation */
  int return_highest_power_of_2 (int i)
  {
    /* find the highest power of 2 <= i */
    short int n = 0;
    for (; pow(2 , n) <= i; ++n)
    {

    }
    return --n;
  }

  int * return_b_number (int n)
  {
    if (n == 0)
      {
        return 0;
      }
    if (n == 1)
      {
        return 1;
      }
    short highest_power_of_2 = return_highest_power_of_2 (n);
    //this needs to be turned into something interesting...
    return return_b_number (n - pow(2, highest_power_of_2)) + pow (2, highest_power_of_2);
  }

  print_b_number (int n)
  {
    //printf("%d\n", return_b_number (n));
  }

  int main ()
  {
    //print_b_number (2);
    //printf ("%d\n", return_highest_power_of_2 (32));
    printf ("%3.0f\n", return_b_number (2));
    printf ("%d\n", (int) return_b_number (2));
    return 0;
  }
#+END_SRC

#+RESULTS:
** printing different things based on the value of variables COOL 
  
   #+HEADERS: :includes <stdio.h> 
   #+BEGIN_SRC C
     for (int i = 0; i < 3; i++)
         printf ("You have %d item%s\n", i, i==1 ? "" : "s");
   #+END_SRC

   #+RESULTS:
   | You | have | 0 | items |
   | You | have | 1 | item  |
   | You | have | 2 | items |

** What is using strcat is bad idea?

:ANSWER:
strcat concatenates two strings.  It is a bad idea, but strcat is a slow method of concatenating two strings.
C does not store the length of strings.  Instead, it has to calculate the length of the strings each time, one
attempts to copy a string.

It may be a better idea to use mempcpy.
:END:

** messing with arrays
Ok, so org-babel should be throwing an error here, but it is not...
#+BEGIN_SRC C  :includes <stdio.h>
int a [8];
a[7] = 3;
a[6] = 4;
a[55] = 1;
a[0] = 2;
printf ("%d %d %d %d\n", a[7], a[6], a[8], a[0]);
#+END_SRC

#+RESULTS:
: 3 4 4198752 2
** highest power of 2

#+BEGIN_SRC C  :includes '("<math.h>" "<stdio.h>")  :flags -lm
  int return_highest_power_of_2 (int i)
  {
    /* find the highest power of 2 <= i */
    short int n = 0;
    for (; pow(2 , n) <= i; ++n)
      {

      }
    return --n;
  }

  int main ()
  {
    short a = return_highest_power_of_2 (0);
    short b = return_highest_power_of_2 (1);
    short c = return_highest_power_of_2 (2);
    short d = return_highest_power_of_2 (3);
    short e = return_highest_power_of_2 (4);
    short f = return_highest_power_of_2 (5);
    short g = return_highest_power_of_2 (6);
    short h = return_highest_power_of_2 (8);
    short i = return_highest_power_of_2 (9);
    short j = return_highest_power_of_2 (10);
    short k = return_highest_power_of_2 (11);
    short l = return_highest_power_of_2 (16);

    printf ("0 %d\n", a);
    printf ("1 %d\n", b);
    printf ("2 %d\n", c);
    printf ("3 %d\n", d);
    printf ("4 %d\n", e);
    printf ("5 %d\n", f);
    printf ("6 %d\n", g);
    printf ("8 %d\n", h);
    printf ("9 %d\n", i);
    printf ("10 %d\n", j);
    printf ("11 %d\n", k);
    printf ("16 %d\n", l);

    return 0;
  }
#+END_SRC

#+RESULTS:
|  0 | -1 |
|  1 |  0 |
|  2 |  1 |
|  3 |  1 |
|  4 |  2 |
|  5 |  2 |
|  6 |  2 |
|  8 |  3 |
|  9 |  3 |
| 10 |  3 |
| 11 |  3 |
| 16 |  4 |
** programs with IPC
All of these things are discussed in the libc manual.
*** sockets
*** PIPES & FIFOs
*** Threads
*** Processes
*** Signals
*** controlling paging
** syslog
** caesar cipher and decrypt program
   
   #+HEADERS: :include <stdio.h>
   #+BEGIN_SRC C
     unsigned int c = 'z';

     printf ("%d", c + 7);
   #+END_SRC

   #+RESULTS:
   : 129

   | a |  97 | A | 65 |

   #+HEADERS: :include <stdio.h>
   #+BEGIN_SRC C
     enum lower_letters { a = 97, b, c, d, e, f, g,
                          h, i, j, k, l, m, n, o,
                          p, q, r, s, t, u, v, w,
                          x, y, z };

     enum upper_letters { A = 65, B, C, D, E, F, G,
                          H, I, J, K, L, M, N, O,
                          P, Q, R, S, T, U, V, W,
                          X, Y, Z };

     enum upper_letters letter = Z; 


     putchar ((int)'z' + 7);
   #+END_SRC

   #+RESULTS:
   : a

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "Probably the simplest case is to decrypt a short sentence." | ./caesar -s 1 | ./caesar -s 25
#+END_SRC

#+RESULTS:
: Probably the simplest case is to decrypt a short sentence.

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "GNU Emacs is Free" | ./caesar -s 1
#+END_SRC

#+RESULTS:
: HOV Fnbdt jt Gsff

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "GNU Emacs is Free" | ./caesar -s 1 | ./decrypt
#+END_SRC

#+RESULTS:
: GNU Emacs is Free

* C bitwise operators
** Bitwise &

The & operator takes two integers, and outputs the bits that are both 1.

|------+---+------|
|   13 | & |   11 |
| 1111 |   | 1100 |
|------+---+------|


Now the bitwise & operation

| 13 | 1101 |
| 11 | 1011 |
|  & |    & |
|----+------|
|  9 | 1001 |

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a, b;
    a = 13;
    b = 11;

    printf("%d\n", a & b);

    a = 0b1101;  //binary 13
    b = 0b1101;  //binary 11

    return 0;
  }

#+END_SRC

#+RESULTS:
: 9
** Bitwise OR |

Bitwise OR is like the propositional logic "\/".

For two binary numbers, the if one bit is a 1, then the answer will have a 1.

|   15 | OR |  3 |
| 1111 |    | 11 |


| 15 | 1111 |
| 13 | 0011 |
| OR |   OR |
|----+------|
| 15 | 1111 |

#+HEADERS :includes  <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a = 15;
    int b = 13;

    printf("%d\n", a|b);

    a = 0b1111;
    b = 0b1101;

    printf("%d\n", a|b);

    return 0;
  }
#+END_SRC

#+RESULTS:
| 15 |
| 15 |
** Bitwise Exclusive OR   XOR   ^


|   17 | OR |    9 |
| 1111 |    | 1001 |


| 17 | 10001 |
|  9 | 01001 |
|  ^ |     ^ |
|----+-------|
| 25 | 11000 |



#+HEADERS :includes  <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a = 17;
    int b = 9;

    printf("%d\n", a|b);

    a = 0b10001;
    b = 0b1001;

    printf("%d\n", a|b);

    return 0;
  }
#+END_SRC

#+RESULTS:
| 25 |
| 25 |
** Bitwise complement Operator  ~

I don't understand this one.  I thought ~13 = 2.

It only works on one operand.  It inverts all bits of one number to the opposite bit.

|  13 | 1101 |
|   ~ |    ~ |
|-----+------|
| -14 | 0010 |   ?????

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
    int main ()
    {
      int i = 13;

      printf("%d\n", ~i);

      i = 0b1101;
      printf("%d\n", ~i);

      return 0;
    }
#+END_SRC

#+RESULTS:
| -14 |
| -14 |
** Shift operators  <<  and   >>


|   1 | <<2 | 1 | <<2 |
|-----+-----+---+-----|
| 100 |     | 4 |     |

The left shift operator moves bits in a number to the left.

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
    int main ()
    {
      int a = 1;
      int b = 0b1;

      printf("%d %d\n", a<<2, b<<2);

      return 0;
    }
#+END_SRC

#+RESULTS:
: 4 4
* The autoconf manual has some examples of buffer overflow and null pointers

  [[info:autoconf#Portable%20C%20and%20C++][info:autoconf#Portable C and C++]]
   
   #+HEADERS: :include <stdio.h>
   #+BEGIN_SRC C
     printf("%c", (char) ((int) 'z' + 1));
   #+END_SRC 
   
   #+RESULTS:
   : {
* Writing userspace C libraries 

http://0pointer.de/blog/projects/libabc.html

https://git.kernel.org/pub/scm/linux/kernel/git/kay/libabc.git/plain/README

